package com.android.openapp.ui;

import java.util.List;

import com.android.openapp.R;
import com.android.openapp.data.Place;
import com.android.openapp.map.LombardiaOverlay;
import com.android.openapp.map.LombardiaOverlayItem;
import com.android.openapp.services.Controller;
import com.android.openapp.services.Controller.ControllerBinder;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;

import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;

/**
 * Fragment che visualizza una mappa
 * ATTENZIONE serve una key fornita da Google per poter visualizzare la mappa
 * la chiave e' associata al keystore
 * https://developers.google.com/maps/documentation/android/mapkey
 * in fase di sviluppo e debugging uso il keystore di debug (default)
 * per conoscere il percorso del keystore debug: 
 * Window->Preferences->Android->Build
 * o usate la key che ho inserito nel file maplayout.xml (e dovete usare il mio stesso keystore)
 * oppure registrate il vostro keystore di debug
 * @author Simone Panza
 *
 */
public class MapFragment extends Fragment implements FragmentInteract{

	ControllerBinder mBinder;
	
	/**
	 * empty constructor, as requested from Android documentation
	 */
	public MapFragment(){
		
	}
	
	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		super.onActivityCreated(savedInstanceState);
		Log.v(MainActivity.TAG, "MapFragment.onActivityCreated()");
		
		MainActivity mActivity = (MainActivity) getActivity();
		mBinder = mActivity.mBinder;
		mActivity.setCurrentFragment(this);
	}
	
	//private final static GeoPoint BERGAMO_GEO_POINT = new GeoPoint(45415604,9401200);
	
	private View mMapViewContainer;
	private MapView mMapView;
	
	private Button mButRefresh;
	private Button mButSearch;
	private Button mButLocation;
	
	//TODO sarebbe utile un bottone stile app di Google maps che ci porta alla posizione corrente
	
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		super.onCreateView(inflater, container, savedInstanceState);
		
		//recupero la MapView che avevo inflatato nella MainActivity
		MainActivity mActivity = (MainActivity) getActivity();
		
		mMapViewContainer = mActivity.mMapViewContainer;
		mMapView = mActivity.mMapView;
		
		//controlli per lo zoom ed eventualmente altre opzioni
		if(mMapView != null){
			//mMapView.setBuiltInZoomControls(true);
			mMapView.setSatellite(false);
			mMapView.getController().setZoom(13); //Ci si posiziona ad uno zoom accettabile
		}
		
		mButRefresh = (Button) mMapViewContainer.findViewById(R.id.button_list_refresh_map);
		mButSearch = (Button) mMapViewContainer.findViewById(R.id.button_list_search_map);
		mButLocation = (Button) mMapViewContainer.findViewById(R.id.button_location_map);
		
		//tasto refresh
		mButRefresh.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				Log.v(MainActivity.TAG,"tasto refresh");
				PlacesListFragment.bookmarkFlag = PlacesListFragment.FLAG_LIST_REFRESH;
				if(mBinder!=null)
					mBinder.getNearPlaces();
			}
		});
		
		//tasto search
		mButSearch.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				PlacesListFragment.bookmarkFlag = PlacesListFragment.FLAG_LIST_REFRESH;
				getActivity().onSearchRequested();
			}
		});
		
		//tasto location
		mButLocation.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				Log.v(MainActivity.TAG,"tasto location");
				Location loc = mBinder.getCurrentLocation();
				if (loc != null){
					GeoPoint g = locationToGeoPoint(loc);
					//mMapView.getController().setCenter(g);
					mMapView.getController().animateTo(g);
				}
			}
		});
		
		return mMapViewContainer;
	}
	
	/**
	 * 
	 * @return lo zoom level piu' adatto al range di ricerca
	 */
	private int getProperZoomLevel() {
		SharedPreferences prefs = getActivity().getSharedPreferences(Controller.MY_PREFS, Context.MODE_PRIVATE);
		int index = prefs.getInt(SettingsFragment.RANGE, 0);
		switch(index){
		case 0: 	// 1 Km
			return 14;
		case 1:		// 5 Km
			return 13;
		default:	//10 Km e piu'
			return 12;
		}
	}
	
	@Override
	public void onDestroyView() {
		super.onDestroyView();
		//devo cancellare la view dal parent altrimenti nella prossima onCreateView esce un'eccezione
		ViewGroup parentViewGroup = (ViewGroup) mMapViewContainer.getParent();
		if (parentViewGroup != null){
			parentViewGroup.removeView(mMapViewContainer);
		}
	}
	
	@Override
	public void onStart() {
		super.onStart();
		showPlacesOnMap(Place.lista);
	}
	
	/**
	 * called when the onServiceConnected() method in the Activity is called
	 */
	@Override
	public void onBind(ControllerBinder binder) {
		mBinder = binder;
		showPlacesOnMap(Place.lista);
	}

	@Override
	public void onDataReceived() {
		//mostro i nuovi posti sulla mappa
		showPlacesOnMap(Place.lista);
	}
	
	private GeoPoint locationToGeoPoint(Location location){
		return coordinatesToGeoPoint(location.getLatitude(), location.getLongitude());
	}
	
	private GeoPoint coordinatesToGeoPoint(double latitude, double longitude){
		int lat = (int) (latitude * 1E6);
		int lon = (int) (longitude * 1E6);
		return new GeoPoint(lat,lon);
	}
	
	private void showPlacesOnMap(List<Place> list){
		//centra la mappa sulla location corrente
		Location loc = mBinder.getCurrentLocation();
		if (loc != null){
			GeoPoint g = locationToGeoPoint(loc);
			mMapView.getController().setCenter(g);
		}
		
		//disegna i marker
		mMapView.getOverlays().clear();
		if(list.size() != 0){
			Drawable Immagine = getResources().getDrawable(R.drawable.marker_blue);
			LombardiaOverlay mOverlay = new LombardiaOverlay(Immagine, getActivity(), mBinder);

			int index = 0;
			for (Place place : list) {
				Double lat = place.getLatitude();
				Double lon = place.getLongitude();
				if (lat != null && lon != null){
					GeoPoint g = coordinatesToGeoPoint(lat,lon);
					mOverlay.addOverlay(new LombardiaOverlayItem(g, place.getDenominazione(), place.getTipologia(), index));
				}
				index++;
			}
			//TODO si potrebbe assegnare un marker di colore diverso per ogni categoria

			mMapView.getOverlays().add(mOverlay);
		}
		mMapView.getController().setZoom(getProperZoomLevel());
		mMapView.postInvalidate();
	}
	
	@Override
	public void onLocationReceived(int listIndex) {
		mMapView.getOverlays().clear();
		Place p = Place.lista.get(listIndex);
		
		Drawable Immagine = getResources().getDrawable(R.drawable.marker_blue);
		LombardiaOverlay mOverlay = new LombardiaOverlay(Immagine, getActivity(), mBinder);
		
		GeoPoint g = coordinatesToGeoPoint(p.getLatitude(), p.getLongitude());
		mOverlay.addOverlay(new LombardiaOverlayItem(g, p.getDenominazione(), p.getTipologia(), listIndex));
		
		mMapView.getController().setCenter(g);
		
		mMapView.getOverlays().add(mOverlay);
		mMapView.getController().setZoom(getProperZoomLevel());
		mMapView.postInvalidate();
	}

	@Override
	public void onBookmarksListUpdated() {
		// TODO Auto-generated method stub
		
	}

}
